package com.chaihu.common.api;

import com.alibaba.fastjson.JSON;
import com.chaihu.bean.in.user.userinfo.QueryUserIn;
import com.chaihu.bean.out.user.userinfo.QueryUserOut;
import com.chaihu.bean.result.ResponseResult;
import com.chaihu.common.dao.UserDao;
import com.chaihu.intf.common.QueryUserInfoService;
import com.chaihu.intf.common.TestService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping(value = "/test")
public class TestApi {

    @Autowired
    private UserDao userDao;
//    @Autowired
//    private UserService userService;

    @Autowired
    private QueryUserInfoService queryUserInfoService;
    @Autowired
    private TestService testService;

    @RequestMapping(value = "/get2", method = RequestMethod.GET)
    public ResponseEntity<Void> get2() {
        testService.test();
        ResponseResult<QueryUserOut> queryUserOutResponseResult = queryUserInfoService.queryUser(new QueryUserIn());
        System.out.println(JSON.toJSONString(queryUserOutResponseResult));
        System.out.println("get2");
        return null;
    }
    @RequestMapping(value = "/get", method = RequestMethod.GET)
    public ResponseEntity<Void> get() {
//        QueryUserIn queryUserIn = new QueryUserIn();
//        queryUserInfoService.queryUser(queryUserIn);
        /*UserDto userDto = new UserDto();
        userDto.setName("张三");
        userDto.setAge("12");
        userDto.setEmail("12@12.com");
        userDto.setMobile("12345678901");
        userDto.setRemark("remarkkk");
        userDto.setCreateBy("zz");
        userDto.setUpdateBy("xx");
        int i = userDao.insert(userDto);
        System.out.println(i);

        List<UserDto> users = userDao.selectRaw();
        users.forEach(System.out::println);*/

//        User user = new User();
//        user.setId(15L);
//        user.setName("我是AR猪");
//        user.setAge(1);
//        user.setEmail("ar@baomidou.com");
//        user.setManagerId(1L);
//        boolean success = user.insert(); // 插入
//        System.out.println(success);
//
//        User user = new User();
//        user.setId(15L);
//        User result = user.selectById();
//        System.out.println(result);
//
//        User user = new User();
//        user.setId(15L);
//        user.setName("王全蛋");
//        user.updateById();
//
//        User user = new User();
//        user.setId(15L);
//        user.deleteById();


//        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
//        wrapper.ge(User::getAge, 28);
//        // 设置分页信息, 查第3页, 每页2条数据
////        Page<User> page = new Page<>(3, 2);
//        Page<User> page = new Page<>(3, 2, false);
//        // 执行分页查询
//        Page<User> userPage = userDao.selectPage(page, wrapper);
//        System.out.println("总记录数 = " + userPage.getTotal());
//        System.out.println("总页数 = " + userPage.getPages());
//        System.out.println("当前页码 = " + userPage.getCurrent());
//        // 获取分页查询结果
//        List<User> records = userPage.getRecords();
//        records.forEach(System.out::println);
//
//        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
//        wrapper.ge(User::getAge, 28).likeRight(User::getName, "王");
//        Page<User> page = new Page<>(3,2);
//        Page<User> userPage = userDao.selectUserPage(page, wrapper);
//        System.out.println("总记录数 = " + userPage.getTotal());
//        System.out.println("总页数 = " + userPage.getPages());
//        userPage.getRecords().forEach(System.out::println);

//        List<User> users = userDao.selectRaw();
//        users.forEach(System.out::println);

//        List<User> list = userDao.selectList(null);

        //只查部分列
//        QueryWrapper<User> wrapper = new QueryWrapper<>();
//        wrapper.select("id","name","email").likeRight("name","黄");
//        List<Map<String, Object>> maps = userDao.selectMaps(wrapper);
//        maps.forEach(System.out::println);
        //进行数据统计
//        QueryWrapper<User> wrapper = new QueryWrapper<>();
//        wrapper.select("manager_id", "avg(age) avg_age", "min(age) min_age", "max(age) max_age")
//                .groupBy("manager_id").having("sum(age) < {0}", 500);
//        List<Map<String, Object>> maps = userDao.selectMaps(wrapper);
//        maps.forEach(System.out::println);

        //只会返回第一个字段（第一列）的值，其他字段会被舍弃
//        QueryWrapper<User> wrapper = new QueryWrapper<>();
//        wrapper.select("id", "name").like("name", "黄");
//        List<Object> objects = userDao.selectObjs(wrapper);
//        objects.forEach(System.out::println);

        //查询满足条件的总数，注意，使用这个方法，不能调用QueryWrapper的select方法设置要查询的列了。这个方法会自动添加select count(1)
//        QueryWrapper<User> wrapper = new QueryWrapper<>();
//        wrapper.like("name", "黄");
//        Integer count = userDao.selectCount(wrapper);
//        System.out.println(count);

//        LambdaQueryWrapper<User> wrapper = Wrappers.<User>lambdaQuery();
//        wrapper.gt(User::getAge, 28);
//        User one = userService.getOne(wrapper, false); // 第二参数指定为false,使得在查到了多行记录时,不抛出异常,而返回第一条记录
//        System.out.println(one);
//
//        List<User> list = userService.lambdaQuery()
//                .gt(User::getAge, 39)
//                .likeRight(User::getName, "王")
//                .list();
//        list.forEach(System.out::println);
//
//        userService.lambdaUpdate()
//                .gt(User::getAge, 39)
//                .likeRight(User::getName, "王")
//                .set(User::getEmail, "w39@baomidou.com")
//                .update();
//
//        userService.lambdaUpdate()
//                .like(User::getName, "青蛙")
//                .remove();

        // 联系条件构造器
        // 案例先展示需要完成的SQL语句，后展示Wrapper的写法

//// 1. 名字中包含佳，且年龄小于25
//// SELECT * FROM user WHERE name like '%佳%' AND age < 25
//        QueryWrapper<User> wrapper = new QueryWrapper<>();
//        wrapper.like("name", "佳").lt("age", 25);
//        List<User> users = userDao.selectList(wrapper);
//// 下面展示SQL时，仅展示WHERE条件；展示代码时, 仅展示Wrapper构建部分
//
//// 2. 姓名为黄姓，且年龄大于等于20，小于等于40，且email字段不为空
//// name like '黄%' AND age BETWEEN 20 AND 40 AND email is not null
//        wrapper.likeRight("name","黄").between("age", 20, 40).isNotNull("email");
//
//// 3. 姓名为黄姓，或者年龄大于等于40，按照年龄降序排列，年龄相同则按照id升序排列
//// name like '黄%' OR age >= 40 order by age desc, id asc
//        wrapper.likeRight("name","黄").or().ge("age",40).orderByDesc("age").orderByAsc("id");
//
//// 4.创建日期为2021年3月22日，并且直属上级的名字为李姓
//// date_format(create_time,'%Y-%m-%d') = '2021-03-22' AND manager_id IN (SELECT id FROM user WHERE name like '李%')
//        wrapper.apply("date_format(create_time, '%Y-%m-%d') = {0}", "2021-03-22") // 建议采用{index}这种方式动态传参, 可防止SQL注入
//                .inSql("manager_id", "SELECT id FROM user WHERE name like '李%'");
//// 上面的apply, 也可以直接使用下面这种方式做字符串拼接，但当这个日期是一个外部参数时，这种方式有SQL注入的风险
//        wrapper.apply("date_format(create_time, '%Y-%m-%d') = '2021-03-22'");
//
//// 5. 名字为王姓，并且（年龄小于40，或者邮箱不为空）
//// name like '王%' AND (age < 40 OR email is not null)
//        wrapper.likeRight("name", "王").and(q -> q.lt("age", 40).or().isNotNull("email"));
//
//// 6. 名字为王姓，或者（年龄小于40并且年龄大于20并且邮箱不为空）
//// name like '王%' OR (age < 40 AND age > 20 AND email is not null)
//        wrapper.likeRight("name", "王").or(
//                q -> q.lt("age",40)
//                        .gt("age",20)
//                        .isNotNull("email")
//        );
//
//// 7. (年龄小于40或者邮箱不为空) 并且名字为王姓
//// (age < 40 OR email is not null) AND name like '王%'
//        wrapper.nested(q -> q.lt("age", 40).or().isNotNull("email"))
//                .likeRight("name", "王");
//
//// 8. 年龄为30，31，34，35
//// age IN (30,31,34,35)
//        wrapper.in("age", Arrays.asList(30,31,34,35));
//// 或
//        wrapper.inSql("age","30,31,34,35");
//
//// 9. 年龄为30，31，34，35, 返回满足条件的第一条记录
//// age IN (30,31,34,35) LIMIT 1
//        wrapper.in("age", Arrays.asList(30,31,34,35)).last("LIMIT 1");
//
//// 10. 只选出id, name 列 (QueryWrapper 特有)
//// SELECT id, name FROM user;
//        wrapper.select("id", "name");
//
//// 11. 选出id, name, age, email, 等同于排除 manager_id 和 javacreate_time
//// 当列特别多, 而只需要排除个别列时, 采用上面的方式可能需要写很多个列, 可以采用重载的select方法，指定需要排除的列
//        wrapper.select(User.class, info -> {
//            String columnName = info.getColumn();
//            return !"create_time".equals(columnName) && !"manager_id".equals(columnName);
//        });
//
//        String name = "黄"; // 假设name变量是一个外部传入的参数
//        QueryWrapper<User> wrapper = new QueryWrapper<>();
//        wrapper.like(StringUtils.hasText(name), "name", name);
//// 仅当 StringUtils.hasText(name) 为 true 时, 会拼接这个like语句到WHERE中
//// 其实就是对下面代码的简化
//        if (StringUtils.hasText(name)) {
//            wrapper.like("name", name);
//        }

//        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
//        wrapper.like(User::getName, "黄").lt(User::getAge, 30);
//        List<User> users = userDao.selectList(wrapper);

//        LambdaQueryChainWrapper<User> chainWrapper = new LambdaQueryChainWrapper<>(userDao);
//        List<User> users = chainWrapper.like(User::getName, "黄").gt(User::getAge, 30).list();
//        users.forEach(System.out::println);

//        LambdaUpdateWrapper<User> wrapper = new LambdaUpdateWrapper<>();
//        wrapper.likeRight(User::getEmail, "share").set(User::getManagerId, 9L);//想要更新的只有那么一列，或者两列
//        userDao.update(null, wrapper);

//        list.forEach(System.out::println);
        return null;
    }
    /**
     * insert(T entity) 插入一条记录
     * deleteById(Serializable id) 根据主键id删除一条记录
     * delete(Wrapper<T> wrapper) 根据条件构造器wrapper进行删除
     * selectById(Serializable id) 根据主键id进行查找
     * selectBatchIds(Collection idList) 根据主键id进行批量查找
     * selectByMap(Map<String,Object> map) 根据map中指定的列名和列值进行等值匹配查找
     * selectMaps(Wrapper<T> wrapper) 根据 wrapper 条件，查询记录，将查询结果封装为一个Map，Map的key为结果的列，value为值
     * selectList(Wrapper<T> wrapper) 根据条件构造器wrapper进行查询
     * update(T entity, Wrapper<T> wrapper) 根据条件构造器wrapper进行更新
     * updateById(T entity)
     */
}
